package com.yang.service.Impl;

import com.alibaba.fastjson.JSON;
import com.yang.entity.Cart;
import com.yang.entity.commodityDetail.Skus;
import com.yang.mapper.CartMapper;
import com.yang.service.CartService;
import com.yang.utils.ThreadLocalUtil;
import jakarta.annotation.Resource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class CartServiceImpl implements CartService {

    @Resource
    private CartMapper cartMapper;

    @Resource
    private MongoTemplate mongoTemplate;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public void addCart(int commodityId, int skuId, int quantity) {
        // 获取用户id
        Map<String, Object> map = ThreadLocalUtil.get();
        int userId = (int) map.get("userId");

        cartMapper.addCart(userId, commodityId, skuId, quantity);
        // 更新redis中的购物车列表
        saveCartTORedis(userId);
    }

    @Override
    public int deleteCart(List<Integer> cartId) {
        // 获取用户对应的cartId
        Map<String, Object> map = ThreadLocalUtil.get();
        int userId = (int) map.get("userId");
        // 根据cartId和userId查询cart
//        Cart cart = cartMapper.getCartById(cartId, userId);
        // 判断cartId是否存在
//        if (cart == null) {
//            return 1;
//        }
        // 调用mapper
        cartMapper.deleteCart(cartId);
        // 更新redis中的购物车列表
        saveCartTORedis(userId);
        return 0;
    }

    @Override
    public int updateCart(int cartId, int quantity) {
        // 获取用户对应的cartId
        Map<String, Object> map = ThreadLocalUtil.get();
        int userId = (int) map.get("userId");
        // 获取redis中的购物车列表
        String cartList = (String) redisTemplate.opsForHash().get("user_" + userId, "cart");
        // 获取redis中购物车列表
        List<Cart> carts = JSON.parseArray(cartList).toJavaList(Cart.class);
        // 判断cartId是否存在
        for (Cart cart : carts) {
            if (cart.getCartId() == cartId) {
                // 更新cart的数量
                cartMapper.updateCartQuantity(cartId, quantity);
                // 更新redis中的购物车列表
                saveCartTORedis(userId);
                return 0;
            }
        }
        // cartId不存在
        return 1;
    }

    @Override
    public List<Cart> listCart() {
        // 结果集
        List<Cart> result = new ArrayList<>();
        // 获取用户id
        Map<String, Object> map = ThreadLocalUtil.get();
        int userId = (int) map.get("userId");

        // 从redis中获取购物车列表
        String cartList = (String) redisTemplate.opsForHash().get("user_" + userId, "cart");
        // 判断redis中是否有购物车列表
        if (cartList != null) {
            result = JSON.parseArray(cartList).toJavaList(Cart.class);
            return result;
        }
        // 从mysql中获取购物车列表
        result = saveCartTORedis(userId);
        return result;
    }

    /**
     * 将mysql中的购物车列表存入redis中
     *
     * @param userId 用户id
     */
    private List<Cart> saveCartTORedis(int userId) {
        // mysql中购物车列表
        List<Cart> result = cartMapper.getCartListByUserId(userId);
        // redis的key
        String key = "user_" + userId;

        for (Cart cart : result) {
            // 获取sku信息，TODO 单次查询次数过多，待优化
            // FIXME mongoDB中的commodityId后期应该变为数字类型
            Query query = new Query(Criteria.where("commodityId").is(String.valueOf(cart.getCommodity().getCommodityId())));
            List<Skus> sku = mongoTemplate.find(query, Skus.class);
            // 获取sku信息
            cart.setSku(sku.getFirst());
        }

        // 将购物车列表存入redis中
        String cartJson = JSON.toJSONString(result);
        redisTemplate.opsForHash().putAll(key, Collections.singletonMap("cart", cartJson));
        // 设置过期时间，此过期时间设置与token存储在一起
        redisTemplate.expire(key, 12, TimeUnit.HOURS);
        return result;
    }
}
